package com.toptech.downloadmanager.download;

import android.app.DownloadManager;
import android.app.Service;
import android.content.AsyncTaskLoader;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v7.widget.MenuPopupWindow;
import android.util.Log;

import com.toptech.downloadmanager.FileInfo;
import com.toptech.downloadmanager.ToolUtils.ContantsUtils;
import com.toptech.downloadmanager.ToolUtils.lg;

import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Time;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IllegalFormatCodePointException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by zhengshaorui on 2017/2/22.
 */

public class DownloadService extends Service {
    private static final String TAG = "zsr";
    private static final int START_DOWNLOAD = 1;
    private static final int FILE_NOT_FOUND = 2;
    private static Context mContext;
    private HashMap<String,DownloadTask> mDownloadMap = new HashMap<>();


    private static ExecutorService sExecutor = Executors.newFixedThreadPool(DownloadTaskManger.TaskCount);


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {

        return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;
    }

    private DownloadServiceBinder mBinder = new DownloadServiceBinder();
    class DownloadServiceBinder extends Binder{

        //all task start download
        public void startAllDownload(List<FileInfo> fileInfos){
            for (FileInfo fileInfo : fileInfos) {

                DownloadTask task = mDownloadMap.get(fileInfo.getApkurl());
                if (task == null){
                    task = new DownloadTask(DownloadService.this,fileInfo.getThreadCount());
                    mDownloadMap.put(fileInfo.getApkurl(),task);
                    task.isPause = false;
                    task.isDelete = false;
                    getFileLengthThread download = new getFileLengthThread(fileInfo);
                    sExecutor.execute(download);
                }


            }
        }

        public void startDownload(FileInfo fileInfo){
            DownloadTask task = mDownloadMap.get(fileInfo.getApkurl());
            if (task == null){
                task = new DownloadTask(DownloadService.this,fileInfo.getThreadCount());
                mDownloadMap.put(fileInfo.getApkurl(),task);
                task.isPause = false;
                task.isDelete = false;
                getFileLengthThread download = new getFileLengthThread(fileInfo);
                sExecutor.execute(download);

            }

            lg.d("start task: "+mDownloadMap.size()+"  "+ mDownloadMap.get(fileInfo.getApkurl()));

        }

        public void pauseDownload(String url){
            DownloadTask task = mDownloadMap.get(url);
            if (task != null && task.isTaskDowning){
                task.pauseDownload();
                mDownloadMap.remove(url);
            }
            lg.d("task: "+mDownloadMap.size());
        }

        public void pauseAllDownload(List<FileInfo> fileInfos){
            for (FileInfo fileInfo : fileInfos){
                DownloadTask task = mDownloadMap.get(fileInfo.getApkurl());
                if (task != null && task.isTaskDowning){
                    task.deleteDownload();
                    mDownloadMap.remove(fileInfo.getApkurl());
                }
            }
        }

        public void deleteDownload(String url){
            DownloadTask task = mDownloadMap.get(url);
            if (task != null && task.isTaskDowning){
                task.deleteDownload();
                mDownloadMap.remove(url);
            }
        }
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        FileInfo fileInfo =  intent.getParcelableExtra("fileinfo");

        Log.d(TAG, "btnstatus: "+fileInfo.getBtnstatus());
        if (fileInfo.getBtnstatus() == ContantsUtils.START){
            DownloadTask task = mDownloadMap.get(fileInfo.getApkurl());
            if (task != null){
                task.isPause = false;
            }
            if (task != null) {
                if (!task.isTaskDowning) {
                    getFileLengthThread download = new getFileLengthThread(fileInfo);
                    sExecutor.execute(download);
                }

            }else{
                getFileLengthThread download = new getFileLengthThread(fileInfo);
                sExecutor.execute(download);
            }

            Log.d(TAG, "task: "+task+" ");

        }else if(fileInfo.getBtnstatus() == ContantsUtils.PAUSE){
            DownloadTask task = mDownloadMap.get(fileInfo.getApkurl());
            if (task != null){
                task.isPause = true;
                mDownloadMap.remove(fileInfo.getApkurl()); //按了暂停，则把这个任务从map剔除，避免重复使用
            }
        }
        Log.d(TAG, "onStartCommand: "+fileInfo);

        return super.onStartCommand(intent, flags, startId);
    }


    /**
     * 启动任务开始下载
     * @param fileInfo
     */
    private synchronized void startDownloadTask(FileInfo fileInfo){
        DownloadTask task = mDownloadMap.get(fileInfo.getApkurl());
        if (task != null){
            task.download(fileInfo, DownloadTaskManger.Holder.getInstance().mDownloadCallback);

        }

    }
    /**
     * 启动线程获取文件的大小，然后开启任务下载文件
     */

    class getFileLengthThread extends  Thread{
        public boolean isfinished = false;
        FileInfo fileinfo;
        public getFileLengthThread(FileInfo fileinfo){
            this.fileinfo = fileinfo;
        }
        @Override
        public void run() {
            super.run();


            HttpURLConnection conn = null;
            try {
                URL url = new URL(fileinfo.getApkurl());
                conn = (HttpURLConnection) url.openConnection();
                conn.setRequestProperty(
                        "Accept",
                        "image/gif, image/jpeg, image/pjpeg, image/pjpeg, " +
                                "application/x-shockwave-flash, application/xaml+xml, " +
                                "application/vnd.ms-xpsdocument, application/x-ms-xbap, " +
                                "application/x-ms-application, application/vnd.ms-excel, "
                               );
                conn.setRequestProperty("Accept-Language", "zh-CN");
                conn.setRequestProperty("Charset", "UTF-8");
                conn.setRequestProperty("Accept-Encoding", "identity");
                conn.setRequestMethod("GET");
                conn.setReadTimeout(5000);
                conn.setConnectTimeout(5000);
                if (conn.getResponseCode() == 200){
                    int length = conn.getContentLength();
                    if (length < 0) return;
                    else fileinfo.setLength(length);
                }

                File dir = new File(fileinfo.getFileDir());
                if (!dir.exists()){
                    dir.mkdir();
                }
                fileinfo.setDir(dir);
                Log.d(TAG, "run: "+ fileinfo);
                isfinished = true;
                startDownloadTask(fileinfo);


            } catch (Exception e) {
                e.printStackTrace();
                Log.d(TAG, "error: "+e.toString());
                fileinfo.setBtnstatus(ContantsUtils.PAUSE);
                int errorCode = ContantsUtils.ERROR_HTTP;
                if (e.toString().contains("already-closed")) //数据库问题
                    errorCode = ContantsUtils.ERROR_SQLITE;
                if (e.toString().contains("FileNotFoundException"))
                    errorCode = ContantsUtils.ERROR_FILE;
                DownloadTaskManger.Holder.getInstance().
                        mDownloadCallback.failed(errorCode,e.toString(),fileinfo);

            }finally {
                if (conn != null) {
                    conn.disconnect();
                }
            }
        }
    }
}
